﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Text.RegularExpressions;
using System.Web.Mvc.Html;
using MvcOSGi.Shell.Version;
using MvcOSGi.Shell.Models;
using BusinessLayer;
using HtmlAgilityPack;

namespace MvcOSGi.Shell.Infra
{
    public static class TemplateExtensions
    {
        public static void RenderTemplate<TModel>(this HtmlHelper<TModel> htmlHelper, string template)
        {
            //Regex regex = new Regex("<template\\s+([^>]+(?:\"|\'))\\s?/?>", RegexOptions.Compiled);
            //var tokens = regex.Split(template);
            //Dictionary<string, string> props = new Dictionary<string, string>();
            //var pageViewModel = htmlHelper.ViewData.Model as PageViewModel;

            Regex regex = new Regex("<*[^>]*data-type=\"component\".*?>(.*?)</*[^>]*>", RegexOptions.Compiled);
            //MatchCollection m = Regex.Matches(template, "<*[^>]*data-type=\"component\".*?>(.*?)</*[^>]*>");


            var tokens = regex.Split(template);
            var values = new List<string>();
            int pos = 0;
            foreach (Match m in Regex.Matches(template, "<*[^>]*data-type=\"component\".*?>(.*?)</*[^>]*>"))
            {
                values.Add(template.Substring(pos, m.Index - pos));
                values.Add(m.Value);
                pos = m.Index + m.Length;
            }
            values.Add(template.Substring(pos));

            Dictionary<string, string> props = new Dictionary<string, string>();
            var pageViewModel = htmlHelper.ViewData.Model as PageViewModel;

            var page = pageViewModel.PageInfo;

            //foreach (var item in values)
            //{
            //    if (item.Contains("data-type='component'"))
            //    { 

            //    }
            //}

            foreach (var item in values)
            {
                if (item.Contains("type=\"component\""))
                {
                    Regex regex1 = new Regex("([^\\s=]+)\\s*=\\s*(\'[^<\']*\'|\"[^<\"]*\")", RegexOptions.Compiled);
                    var attributes = regex1.Matches(item.ToString()).Cast<Match>();
                    props = attributes.ToDictionary(k => k.Value.Split(new char[] { '=' }, StringSplitOptions.RemoveEmptyEntries).First(), v => v.Value.Split(new char[] { '=' }, StringSplitOptions.RemoveEmptyEntries).Last());

                    if (props != null)
                    {
                        string componentName = props["data-name"].Replace("\"", string.Empty);
                        var plugin = page.Plugins.Where(p => p.PluginName.Equals(componentName, StringComparison.InvariantCultureIgnoreCase)).FirstOrDefault();
                        if (plugin == null)
                        {
                            htmlHelper.RenderAction("Error", "Home");
                        }
                        else
                        {
                            htmlHelper.RenderAction(plugin.Mode, plugin.PluginName, new { plugin = plugin.PluginName, data = pageViewModel.DataBag });
                        }
                    }
                }
                else
                {
                    htmlHelper.ViewContext.Writer.Write(item);
                }
            }
        }

        public static void RenderTemplateComponent<TModel>(this HtmlHelper<TModel> htmlHelper, string component)
        {
            htmlHelper.RenderPartial(component, htmlHelper.ViewData.Model);

            string template = "<div class='test'><template name='test' prop1='1'/></div>";
            Regex regex = new Regex("<template\\s+([^>]+(?:\"|\'))\\s?/?>", RegexOptions.Compiled);
            var tokens = regex.Matches(template);
            Dictionary<string, string> props = new Dictionary<string, string>();
            foreach (var item in tokens)
            {
                Regex regex1 = new Regex("([^\\s=]+)\\s*=\\s*(\'[^<\']*\'|\"[^<\"]*\")", RegexOptions.Compiled);
                var attributes = regex1.Matches(item.ToString()).Cast<Match>();
                props = attributes.ToDictionary(k => k.Value.Split(new char[] { '=' }, StringSplitOptions.RemoveEmptyEntries).First(), v => v.Value.Split(new char[] { '=' }, StringSplitOptions.RemoveEmptyEntries).Last());

            }
            regex.Replace(template, "Test" + props.Keys.FirstOrDefault());
        }

        public static IHtmlString VersionHtml<TModel>(this HtmlHelper<TModel> htmlHelper, string value) where TModel : PageViewModel
        {
            if (!string.IsNullOrWhiteSpace(value))
            {
                if (value.EndsWith(".htm", StringComparison.OrdinalIgnoreCase)
                    || value.EndsWith(".html", StringComparison.OrdinalIgnoreCase))
                {
                    try
                    {
                        //Read version html from some location and use it as template
                        //string fileName = AppActions.GetResourcePathFor(CompanyDB.CompanyFolderType.ImgCustom, htmlHelper.ViewData.Model, value);
                        //value = File.ReadAllText(fileName);
                    }
                    catch
                    {
                        value = string.Empty;
                    }
                }
                var pageViewModel = htmlHelper.ViewData.Model as PageViewModel;
                var company = pageViewModel.DataBag.GetResult<Company.Company>(BusinessLayer.Enums.DataBagKey.BaseData).FirstOrDefault();
                value = value.Replace(Enums.ComponentVariable.VersionPath.GetDescription(), string.Concat("assets", company.AssetLocation, pageViewModel.VersionInfo.VersionID, "/"));
                HtmlDocument htmlDocument = new HtmlDocument();
                htmlDocument.LoadHtml(value);
                foreach (HtmlNode componentNode in htmlDocument.DocumentNode.SelectNodes("//*[@data-type='component']"))
                {
                    componentNode.InnerHtml = string.Empty;
                }
                value = htmlDocument.DocumentNode.OuterHtml;
            }
            return new HtmlString(value);
        }
    }
}